package com.common.log;

import cn.hutool.core.util.IdUtil;
import com.entity.sys.SysLog;
import com.entity.sys.SysUser;
import com.service.sys.SysLogService;
import fuhua.com.anno.Log;
import fuhua.com.util.IPUtil;
import fuhua.com.util.ResultUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Aspect
@Component
public class LogAspect {

    @Resource
    private SysLogService sysLogService;

    /**
     * 此处的切点是注解的方式，也可以用包名的方式达到相同的效果
     */
    @Pointcut("@annotation(fuhua.com.anno.Log)")
    public void log(){}

    /**
     * 环绕增强，相当于MethodInterceptor
     */
    @Around("log()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object res = null;
        try {
            res =  joinPoint.proceed();
            return res;
        } finally {
            try {
                //方法执行完成后增加日志
                addOperationLog(joinPoint,res);
            }catch (Exception e){
                System.out.println("LogAspect 操作失败：" + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    private void addOperationLog(JoinPoint joinPoint, Object res){
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Log annotation = signature.getMethod().getAnnotation(Log.class);
        if(annotation != null){
            //拦截到请求
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            //获取请求
            HttpServletRequest request = attributes.getRequest();
            //获取响应
            HttpServletResponse response = attributes.getResponse();
            SysUser user = sysLogService.getLoginUser();
            SysLog sysLog = new SysLog(IPUtil.getIpAddress(request),annotation.title(),signature.getMethod().getName());
            sysLog.setId(IdUtil.fastSimpleUUID());
            sysLog.setCreateBy(user.getUserName());
            setState(sysLog,res,response);
            //保存日志
            sysLogService.save(sysLog);
        }
    }

    /**
     * 处理状态
     */
    private void setState(SysLog sysLog,Object res,HttpServletResponse response){
        //获取是否执行成功状态吗
        if (response.getStatus()!=200){
            sysLog.setState("操作失败");
            sysLog.setInfo(sysLog.getCreateBy()+sysLog.getTitle()+"失败");
        }else {
            //获取返回结果
            ResultUtil ResultUtil = (ResultUtil) res;
            sysLog.setState("操作成功");
            //如果code不为0，说明有错误，设置日志状态为失败，并记录错误信息
            if (ResultUtil.getCode()!=0){
                sysLog.setState("操作失败");
                sysLog.setInfo(sysLog.getCreateBy()+sysLog.getTitle()+"失败："+ResultUtil.getMessage());
            }else {
                sysLog.setInfo(sysLog.getCreateBy()+sysLog.getTitle()+"成功");
            }
        }
    }
}
